package com.example.om_export.system.log;

import com.example.om_export.common.utils.BaseUtil;
import com.example.om_export.system.log.entity.OptLogger;
import com.example.om_export.system.log.service.OptLogService;
import com.example.om_export.system.log.util.WebLoggerUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * 	操作日志aop切面
 * @author 80511
 */
@Aspect
@Component
public class OptLogAspect {

    private final Logger log=LoggerFactory.getLogger(OptLogAspect.class);

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private OptLogService optLogService;

    /**
     *  切点
     */
    @Pointcut("@annotation(com.example.om_export.system.log.OptLog)")
    public void optLog() {}

    /**
     * 后置通知
     */
    @After("optLog()")
    public void after(JoinPoint joinPoint) {
        log.info("对@optLog()注进行后置切入 ");
        MethodSignature ms = (MethodSignature) joinPoint.getSignature();
        try {
            Method method = joinPoint.getTarget().getClass().getDeclaredMethod(ms.getName(), ms.getParameterTypes());
            OptLog opLog = method.getAnnotation(OptLog.class);

            OptLogger optLogger=null;
            if(opLog.auto()) {//自动封装日志对象
                optLogger=new OptLogger();
                baseInfo(optLogger);
                optLogger.setOptModule(opLog.module());//从注解中获取模式信息
                optLogger.setOptInfo(opLog.info());//详情
                optLogger.setRemark(opLog.remark());//备注
            }else {
                optLogger=OptLogConstant.OPT_LOG.get();//获取注解变量中的对象
                OptLogConstant.OPT_LOG.set(null);
                if(optLogger!=null) {
                    baseInfo(optLogger);
                }else {
                    log.warn("使用了@optLog()注解atuo=false，但是并没有向注解变量OptLogConstant.OPT_LOG中写入日志对象a");
                }
            }
            //插入日志对象
            if(optLogger!=null)optLogService.addOptLogger(optLogger);

        } catch (NoSuchMethodException | SecurityException e) {
            e.printStackTrace();
        }
    }

    /**
     * 	封装基础信息
     * @param optLogger
     */
    private void baseInfo(OptLogger optLogger) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        optLogger.setId(BaseUtil.uuid());//设置id
//        if(UserUtil.getUser() != null){
//            optLogger.setOptUser(UserUtil.getUser().getUserName());//当前用户id
//        }
        optLogger.setIpAddress(WebLoggerUtils.getCliectIp(request));//当前ip
        optLogger.setCreated(new Date());//创建时间
        optLogger.setReferer(request.getHeader("Referer").replaceAll("(http|https)://[\\w\\.:]++", ""));//请求url
        optLogger.setRequestUrl(request.getRequestURI());//当前controller对应url
        HttpServletResponse response = attributes.getResponse();

        // 获取请求错误码
        int status = response.getStatus();
        // 设置返回错误码
        optLogger.setType(status);
    }
}

